package http

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"

	s "gitee.com/xiaoa7/jsetl/service"
	jsvmcore "gitee.com/xiaoa7/jsvm-core"
	"github.com/dop251/goja"
)

// 获取数据库实例
func getInstance(id string) (*Http, error) {
	if ins := s.GetService(id); ins != nil {
		if _http, ok := ins.(*Http); ok {
			return _http, nil
		} else {
			return nil, errors.New("http instance type error")
		}
	}
	return nil, errors.New("can't find http instance")
}

// 发送api请求，获取数据
func (h *Http) Request(method, href string, header map[string]interface{},
	param map[string]interface{},
	timeout int64) (interface{}, error) {
	// 创建自定义 Transport
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}

	// 创建客户端
	var client *http.Client
	if strings.HasPrefix(href, "https") {
		client = &http.Client{Transport: tr,
			Timeout: time.Duration(timeout) * time.Second,
		}
	} else {
		client = &http.Client{
			Timeout: time.Duration(timeout) * time.Second,
		}
	}
	//请求参数拼装
	var rawBs []byte

	if v, ok := header["content-type"]; ok {
		contentType, _ := v.(string)
		if strings.Contains(contentType, "json") {
			rawBs, _ = json.Marshal(param)
		}
	} else {
		body := new(strings.Builder)
		for k, v := range param {
			body.WriteString(fmt.Sprintf("%s=%v&", k, v))
		}
		rawBs = []byte(body.String())
	}

	if v, ok := header["request-param-type"]; ok {
		if v == "rawtext" {
			data, _ := param["data"].(string)
			rawBs = []byte(data)
		}
	}
	req, err := http.NewRequest(method, href, bytes.NewReader(rawBs))
	if err != nil {
		return nil, err
	}
	for k, v := range header {
		value, _ := v.(string)
		req.Header.Set(k, value)
	}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	bs, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	//修复header
	rawHeader := map[string]string{}
	for k, v := range resp.Header {
		rawHeader[k] = strings.Join(v, "\n")
	}
	ret := struct {
		Header map[string]string `json:"header"`
		Body   string            `json:"body"`
	}{
		rawHeader,
		string(bs),
	}
	resp.Body.Close()
	return ret, nil
}

// 初始化
func init() {
	jsvmcore.RegisterObject("http", map[string]jsvmcore.HandleFn{
		"init": func(vm *jsvmcore.JsVM) jsvmcore.JsVmFn {
			return func(params ...interface{}) goja.Value {
				if len(params) < 1 {
					return vm.State.ToValue("无效的输入参数")
				}
				httpInstance, _ := params[0].(string)
				generateService(httpInstance)
				return vm.State.ToValue("ok")
			}
		},
		//http请求
		"request": func(vm *jsvmcore.JsVM) jsvmcore.JsVmFn {
			return func(params ...interface{}) goja.Value {
				if len(params) < 6 {
					return vm.State.ToValue("无效的输入参数")
				}
				method, _ := params[1].(string)
				href, _ := params[2].(string)
				header, _ := params[3].(map[string]interface{})
				param, _ := params[4].(map[string]interface{})
				timeout, _ := params[5].(int64)
				httpInstance, _ := params[0].(string)
				if ins, err := getInstance(httpInstance); err == nil {
					if ret, err := ins.Request(method, href, header, param, timeout); err == nil {
						return vm.State.ToValue(ret)
					} else {
						return vm.State.ToValue(err)
					}
				} else {
					return vm.State.ToValue(err.Error())
				}

			}
		},
	})
}
